home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * ispCODE5D.c *
- * ispCODE for ispLSI 2000V Devices *
- * Lattice Semiconductor Corp. Copyright 1996. *
- * *
- * ISP(tm) daisy chain turbo programming is supported by ispCODE. *
- * *
- * The function of ispCODE is to step the IEEE 1149.1 TAP state machine *
- * in the ispLSI devices for programming and verification. The input file *
- * for ispCODE is SLIM ispSTREAM file. *
- * *
- * The file size of SLIM ispSTREAM is at least 50% less than the FULL *
- * ispSTREAM. The saving comes from stripping out the instructions and field *
- * size identifiers. The code size of ispCODE V5.00 for processing the SLIM *
- * ispSTREAM is also reduced by 50% as a result. *
- * *
- * The file size of Super SLIM ispSTREAM is about 50% less than the SLIM *
- * ispSTREAM. The extra saving comes from replacing long chain of 0xFFs with *
- * the number of consecutive 0xFF bytes. For example: *
- * 0xFF,0xFF,0xFF,0xC3 is reduced to 0xFF,0x02,0xC3 *
- * *
- * The only restriction on the SLIM ispSTREAM is that the daisy chain must be*
- * of the same ISP device types. For example: *
- * A chain of ispLSI 2000V devices. *
- * *
- * The SLIM ispSTREAM file is created by the command line program dld2isp.exe*
- * v4.02 with the option s selected. For example: type *
- * dld2isp design.dld s *
- * The Super SLIM ispSTREAM file is created by the command line program *
- * dld2isp.exe v4.03 with the option ss selected. For example: type *
- * dld2isp design.dld ss *
- * *
- * The program isp2hex.exe and the source code isp2hex.c can be used to *
- * convert the ispSTREAM file from binary format to C code for linking with *
- * ispcode5.c. *
- * *
- * All ispLSI 2000LV family of devices support the IEEE 1149.1 32-bit *
- * USERCODE. The USERCODE data must be appended into the JEDEC file if it *
- * is to be programmed into the device. The UES editor on the ISP Daisy *
- * Chain Download should be used to add or modify the USERCODE data. *
- * It is important to note that USERCODE is only 32 bits long. The extra *
- * bits will still be written into the JEDEC file but will be discarded *
- * during USERCODE programming if more than 32 bits of data is entered *
- * on the UES editor. *
- * *
- * Programming and verification always include all Array Cells and the *
- * entire USERCODE. The USERCODE is programmed to be FFFFFFFF in hex by *
- * default. *
- * *
- * The procedure of reading USERCODE is as follows: *
- * 1. Raise TMS to VIH and pulse TCK 6 times to step to Test-Logic Reset *
- * state. *
- * 2. TMS to VIL, pulse TCK 1 time. *
- * 3. TMS to VIH, pulse TCK 2 times. *
- * 4. TMS to VIL, pulse TCK 2 times to step to Shift-IR state. *
- * 5. TMS stay at VIL, shift in the VERIFY_USERCODE instruction 10111 *
- * into the IR via TDI and pulse TCK. The instruction is shifted in *
- * from right to left, i.e. 1, 1, 1, 0 and 1. Repeat the instruction *
- * if there is more than one ispLSI device in the chain. Raise TMS to *
- * VIH while shifting in the last bit. *
- * 6. Keep TMS at VIH, pulse TCK 2 times to step to Select-DR-Scan state. *
- * 7. TMS to VIL, pulse TCK 2 times to step to Shift-DR state. *
- * 8. Keep TMS at VIL, pulse TCK 32 times to shift out the 32 bits *
- * USERCODE on TDO. Pulse TCK 32 times more if more than one device *
- * in the chain. Raise TMS to VIH while shifting out the last bit. *
- * *
- * 9. Keep TMS at VIH and pulse TCK 6 times to go back to Test-Logic *
- * Reset state to end the procedure. *
- * *
- * Revision history: *
- * 5D.000 Howard Tang 11/12/96 Convert from 5C.0 to support programming *
- * using the IEEE 1149.1 TAP for ispLSI *
- * 2000LV family of devices. *
- *****************************************************************************/
-
- #include <stdio.h>
- #include <dos.h>
- #include <stdlib.h>
- #include <string.h>
- #include "lattice.h"
- #include "istream.hex"
-
- /*Global variables */
- static unsigned char curch; /*the current data from ispSTREAM*/
- unsigned char *fp; /*pointer to the ispSTREAM*/
- static short int bit=0; /*the current bit read from ispSTREAM*/
-
- static short int inputport=inport1, /*port address for the input port*/
- outputport=outport1; /*port address for the output port*/
- static short int isp_pins=NUL; /*3.02 holds the value of parallel port*/
- /* intialized to drive all pins to LOW*/
- static char state; /*4.0 Keep track of the state of the TAP
- state machine.*/
- /*prototypes*/
- void pulse_width(unsigned short int milliseconds);
- void execute(void);
- void move_to_id_state(void);
- short int ispstream_pump(short int operation, short int *end);
- void error_handler(short int rcode, char *message);
- unsigned char GetByte(void);
- void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse,
- short int *ProgramPulse, short int *RowLength,
- unsigned short int *DataSize,
- unsigned short int *IDStreamLength);
- char ispRead(unsigned short int DataSize, unsigned char *OutData);
- void ReadispSTREAMData(unsigned short int DataSize, unsigned char *InData,
- char SS);
- void ispInstruction(short int ChipCount, unsigned char Command);
- void ispAddress(short int ChipCount, short int RowLength);
- void ispData( unsigned char *InData, unsigned short int DataSize);
- void program_enable(short int chips);
- void device_enable(short int chips);
-
- /***************************************************************************
- Function: isp_setpin(byte pins, byte value)
-
- Purpose:
- To apply the specified value to the pins indicated. This routine will
- likely be modified for specific systems. As an example, this code
- is for the PC, as described below.
-
- This routine uses the IBM-PC standard Parallel port, along with the
- schematic shown in Lattice documentation, to apply the signals to the
- programming loop.
-
- PC Parallel port pin Signal name
- -------------------- -----------
- 2 out_SDI
- 3 out_SCLK
- 4 out_MODE
- 5 out_ISP
- 6 out_RESET
- 7 DO5
- 8 out_SENSE_CABLE_OUT
- 9 DO7
- 10 in_SDO
- 12 in_CABLE_SENSE_IN
- 15 in_VCC_OK
- 20 GND
-
- Parameters:
- - pins, which is actually a set of bit flags (defined in lattice.h)
- that correspond to the bits of the data port. Each of the I/O port
- bits that drives an isp programming pin is assigned a flag
- (through a #define) corresponding to the signal it drives. To
- change the value of more than one pin at once, the flags are added
- together, much like file access flags are.
-
- The bit flags are only set if the pin is to be changed. Bits that
- do not have their flags set do not have their levels changed. The
- state of the port is always manintained in the static global
- variable isp_pins, so that each pin can be addressed individually
- without disturbing the others.
-
- - value, which is either HIGH (0x01 ) or LOW (0x00 ). Only these two
- values are valid. Any non-zero number sets the pin(s) high.
-
- Returns: nothing.
-
-
- **************************************************************************/
- void isp_setpin(unsigned char pins, unsigned char value)
- {
- /* isp_pins is a Global value that keeps track of the current state
- of the pins */
-
- if( value ) /* set flagged pins HIGH */
- isp_pins = pins | isp_pins;
- else /* set flagged pins LOW */
- isp_pins = ~pins & isp_pins;
-
- /* value is put on Parallel port pins */
- outp(outputport, isp_pins);
-
- } /* isp_setpin() */
-
-
- /***************************************************************************
- Function: isp_SDO()
-
- Purpose:
- To get the value of the SDO pin from the input port.
-
- This routine is specific to the PC parallel port setup, but can easily
- be changed to address each user's hardware.
-
- Parameters: none
-
- Returns: The value of SDO, as a byte, with a value of either 0 or 1.
-
- Notes:
- - This routine uses the I/O port addresses contained in the global
- variable inputport, declared in the lattice.h file.
-
- ****************************************************************************/
- unsigned char isp_SDO(void)
- {
- /* MUST return either 0x00 or 0x01 */
- return( (unsigned char) ((inp(inputport) & in_SDO ) ? HIGH : LOW) );
-
- } /* isp_SDO() */
-
- /*************************************************************
- * *
- * PULSE_WIDTH *
- * This procedure produce accurate timing only on straight PC *
- * DOS. The timing is not guarantee if use on Windows DOS. *
- * The delay() function is available only from BORLAND. *
- * *
- * Users must devise their own timing procedures to ensure *
- * the specified minimum delay is observed when using *
- * different platform. *
- *************************************************************/
-
-
- void pulse_width(unsigned short int milliseconds)
- {
- delay(milliseconds);
- }
-
- /*************************************************************
- * *
- * GETBYTE *
- * This procedure reads a byte from the ispSTREAM. *
- *************************************************************/
- unsigned char GetByte()
- {
- return (*fp++);
- }
-
-
- /*************************************************************
- * *
- * SCLOCK *
- * This procedure apply a clock to TCK. *
- *************************************************************/
- void sclock(void)
- {
- isp_setpin(out_SCLK,HIGH);
- isp_setpin(out_SCLK,LOW);
- }
-
- /*************************************************************
- * *
- * SHIFT/EXECUTE *
- * This procedure walk all devices in the daisy chain from a *
- * given state to the next desirable state. *
- * *
- *If at Idle state when enter then move to Shift-IR state. *
- *If at Shift-IR state when enter then move to Shift-DR state.*
- *If at Shift-DR state when enter then move to Shift-IR state.*
- *If at Shift-IR state and state is set to time_state when *
- *enter then move to Idle state. *
- *************************************************************/
- void execute()
- {
- short int i,count;
- if (state==time_state)
- {count = 1; /*move from shift-IR to Idle state to start timing*/
- state = idle_state;
- }
- else if (state==shift_state)
- {count = 2; /*move from shift-IR to shift-DR*/
- state = execute_state;
- }
- else if (state==idle_state)
- {count = 2; /*move from Idle to shift-IR state*/
- state = shift_state;
- }
- else if (state==execute_state)
- {count = 3; /*move from shift-DR to shift-IR*/
- state = shift_state;
- }
- else count = 0;
- isp_setpin(out_SCLK,LOW);
- isp_setpin(out_MODE,LOW);
- isp_setpin(out_SDI,LOW);
- for (i=0; i<count; i++)
- {
- isp_setpin(out_MODE,HIGH);
- sclock();
- }
- isp_setpin(out_MODE,LOW);
- sclock();
- if (count > 1) sclock();
- /* at Shift-DR or Shift-IR state*/
-
- }
-
-
- /*************************************************************
- * *
- * MOVE TO ID STATE *
- * This procedure walk all devices in the daisy chain to the *
- * Test-Logic-Reset state then Run-Test/Idle state. *
- * *
- *************************************************************/
-
- void move_to_id_state()
- {
- short int i;
- isp_setpin(out_SCLK,LOW);
- isp_setpin(out_MODE+out_SDI,LOW);
- pulse_width(2);
- isp_setpin(out_MODE,HIGH);
- pulse_width(2);
- isp_setpin(out_SCLK,HIGH);
- pulse_width(2);
- isp_setpin(out_SCLK,LOW);
- for (i=0; i<6; i++) sclock();
- isp_setpin(out_MODE,LOW);
- pulse_width(2);
- sclock(); /*device is in Idle state*/
- state = idle_state;
- }
-
- /*************************************************************
- * *
- * PROGRAM ENABLE *
- * perform the 3 read id instruction to get devices into *
- * programming mode. *
- *************************************************************/
-
- void program_enable(short int chips)
- {
- short int i,j,loops;
-
- for (loops=0; loops<3; loops++)
- {
- for (i=0; i<chips+1; i++)
- for (j=0; j<5; j++) /*send the instruction into TDI*/
- {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH); /*last bit*/
- isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
- sclock();
- }
- for (i=0; i<3; i++) sclock();
- isp_setpin(out_MODE,LOW);
- sclock(); sclock(); /*devices at Shift-IR state*/
-
- }
- }
-
- /*************************************************************
- * *
- * DEVICE ENABLE *
- * perform the read id instruction to get devices into *
- * functional mode. *
- *************************************************************/
-
- void device_enable(short int chips)
- {
- short int i,j;
-
- /*devices come in at Shift-IR state*/
- for (i=0; i<chips+1; i++)
- for (j=0; j<5; j++) /*send the instruction into TDI*/
- {if ((i==chips)&&(j==4)) isp_setpin(out_MODE,HIGH); /*last bit*/
- isp_setpin(out_SDI,(PROGRAM_ENABLE >> j) & 0x01);
- sclock();
- }
- sclock(); /*devices at Update-IR state*/
- isp_setpin(out_MODE,LOW);
- for (i=0; i<20; i++) sclock(); /*go and loop on Run-Test/Idle for 10uS*/
- isp_setpin(out_MODE,HIGH);
- for (i=0; i<3; i++) sclock(); /*devices at Test-Logic-Reset and active*/
- }
-
- /*************************************************************
- * *
- * READ_ISPSTREAM_HEADER *
- * Extract the header from the ispSTREAM file. *
- * Return *
- * ChainLength--------number of ispLSI devices in the *
- * given daisy chain. *
- * ErasePulse---------pulse width in mS for device *
- * bulk erase. *
- * ProgramPulse-------pulse width in mS for device *
- * row by row programming. *
- * RowLength----------the number of rows of data +UES *
- * DataSize-----------the size of each row of data *
- * IDStreamLength-----the bit length of the ID stream. *
- *************************************************************/
- void ReadispSTREAMHeader(short int *ChainLength, short int *ErasePulse,
- short int *ProgramPulse, short int *RowLength,
- unsigned short int *DataSize,
- unsigned short int *IDStreamLength)
- {
-
- *ChainLength = GetByte();
- *ErasePulse = GetByte() * 0x100;
- *ErasePulse += GetByte();
- *ProgramPulse = GetByte();
- *RowLength = GetByte() * 0x100;
- *RowLength += GetByte();
- *DataSize = GetByte() * 0x100;
- *DataSize += GetByte();
- *IDStreamLength = GetByte() * 0x100;
- *IDStreamLength += GetByte();
- /*End of the header of the ispSTREAM file.*/
-
- }
-
- /*****************************************************************
- * *
- * READ_ISPSTREAM_DATA *
- * Extract the data from the ispSTREAM file. *
- * DataSize-----------The number of data bits to be fetched. *
- * SS-----------------Super SLIM ispSTREAM file if true. *
- * Return *
- * InData-------------The data stream from ispSTREAM file *
- ******************************************************************/
- void ReadispSTREAMData(unsigned short int DataSize, unsigned char *InData,
- char SS)
- {
- unsigned short int index;
- short int i,j;
- unsigned char xch;
- static short int FFcount=0; /*5.1*/
-
- j=0;
- xch=0;
- for (index=0; index<DataSize; index++)
- {--bit;
- if (bit<0)
- {if (FFcount<=0) /*5.1 Read a new byte if 0xFF chain exhausted*/
- { curch = GetByte();
- if ((SS)&&(curch==0xFF)) /*5.1 Super SLIM ispSTREAM file support*/
- FFcount = GetByte(); /*5.1 The number of 0xFF bytes*/
- }
- else FFcount--; /*5.1 Use up the 0xFF chain first*/
- bit=7;
- }
- if ((curch >> bit) & 0x01) xch |= 0x80 >> index%8;
- if (index%8==7) {InData[j++] = xch; xch=0;}
- }
- InData[j] = xch; /*save the last byte of the current row*/
- }
-
- /*************************************************************
- * *
- * ispInstruction *
- * Send the instruction streams to the devices. *
- * ChipCount-------The number of devices in the chain. *
- * Command---------The command to be sent to all devices. *
- *************************************************************/
- void ispInstruction(short int ChipCount, unsigned char Command)
- {
- char Instruction = 5; /*All Lattice devices have 5 bit commands*/
- short int index;
- short int i;
- for (index = 0; index < ChipCount; index++) {
- for (i=0; i<Instruction; i++)
- {isp_setpin(out_SDI, (Command >> i)&0x01);
- if ((index==ChipCount-1)&&(i==Instruction-1))
- isp_setpin(out_MODE,HIGH); /*shift in the last bit*/
- sclock(); /*clock the data into the command registers */
- }
- }
- execute();
- }
-
- /*************************************************************
- * *
- * ispAddress *
- * Send the Address streams to the devices. *
- * ChipCount-------The number of devices in the chain. *
- * Address---------The full address for the devices. *
- *************************************************************/
- void ispAddress(short int ChipCount, short int RowLength)
- {
- short int index;
- short int i;
- unsigned short int condition; /*0x1000 HD devices*/
- /*0x2000 HD devices with UES*/
- /*0x3000 Single row per address HD devices*/
- /*0x4000 Single row per address HD devices with UES*/
-
- condition = RowLength & 0xF000;
- RowLength = RowLength & 0x0FFF; /*Mask out the condition bits*/
- if ((condition==0x2000)||(condition==0x4000))
- RowLength = (RowLength-1)/2; /*Exclude the USERCODE from address*/
- else if ((condition==0x1000)||(condition==0x3000))
- RowLength = RowLength/2; /*High Low Order addressing*/
-
- for (index = 0; index < ChipCount; index++) {
- for (i=1; i<RowLength; i++)
- sclock(); /*clock zeros into the address registers */
- isp_setpin(out_SDI,HIGH);
- if (index==ChipCount-1)
- isp_setpin(out_MODE,HIGH); /*shift in the last bit*/
- sclock(); /*clock a one into the address registers*/
- isp_setpin(out_SDI,LOW);
- }
- execute(); /*step to shift-IR state*/
- }
-
- /**********************************************************************
- * *
- * ispData *
- * Send the data stream to devices. *
- * InData-----------The data stream to be sent to devices. *
- * DataSize---------The length of the data stream. *
- ***********************************************************************/
- void ispData(unsigned char *InData, unsigned short int DataSize)
- {
- unsigned short int index;
- short int i,j;
- unsigned char xch;
-
- j=0;
- for (index = 0; index <DataSize; index++) {
- if (index%8==0) xch = InData[j++];
- isp_setpin(out_SDI, (((xch << index%8) & 0x80) ? 0x01 : 0x00));
- if (index==DataSize-1)
- isp_setpin(out_MODE,HIGH); /*shift in the last bit*/
- sclock(); /*clock data into the data shift registers */
- }
- execute(); /*step to shift-IR state*/
- }
-
- /**********************************************************************
- * *
- * ispRead *
- * Read the data stream from devices and verify. *
- * DataSize---------The length of the data stream. *
- * OutData----------The data stream to be compare with those read *
- * from devices. *
- ***********************************************************************/
- char ispRead(unsigned short int DataSize, unsigned char *OutData)
- {
- unsigned short int index,error;
- short int i,j;
- unsigned char xch,cur_bit;
-
- j=0;
- error=0;
- xch=0;
- for (index = 0; index <DataSize; index++) {
- if (index%8==0) xch = OutData[j++];
- cur_bit=isp_SDO();
- if (cur_bit != (((xch << index%8) & 0x80) ? 0x01 : 0x00))
- error++;
- if (index==DataSize-1)
- isp_setpin(out_MODE,HIGH); /*shift in the last bit*/
- sclock(); /*clock data out from the data shift registers */
- }
- execute(); /*step to shift state*/
- if (error > 0) return 1; /*Flag failure occur*/
- else return (0);
- }
-
- /*************************************************************
- * *
- * ISPSTREAM_PUMP *
- * *
- *************************************************************/
-
- short int ispstream_pump(short int operation, short int *end)
- {
- short int row;
- short int HighLow; /*device types identifiers*/
- char SS; /*ispSTREAM file types identifier*/
- unsigned char Command,UES,FileType;
- short int last_row,
- erase_pulse,
- program_pulse,
- devices_in_chain;
- unsigned short int maxi_data,
- data_length,
- id_length;
- short int rcode;
- short int DeviceType,EndRow;
- unsigned char *buf;
-
- row =0;
- bit = 0;
- /*Start reading the header of the ispSTREAM file*/
- fp = ispstream;
- FileType = GetByte();
- if (FileType == 0x01) {SS=false;} /*Check for correct file type*/
- else if (FileType == 0x03 ) {SS=true;} /*Super SLIM ispSTREAM file found*/
- else {
- return FILE_NOT_JEDEC;
- }
- ReadispSTREAMHeader(&devices_in_chain, &erase_pulse, &program_pulse,
- &last_row, &maxi_data, &id_length);
-
- rcode = OK; /*Success by default.*/
- DeviceType = last_row & 0xF000; /*Device types code*/
- EndRow = last_row & 0x0FFF; /*Actual address length*/
- if ((DeviceType == 0x1000) || (DeviceType == 0x2000))
- HighLow = true; /*Devices need High/Low addressing detected*/
- else HighLow = false;
- if ((DeviceType==0x2000)||(DeviceType==0x4000))
- UES=true; /*UES programming required*/
- else UES=false;
- if ((operation==verify)||(operation==verify_ues)) /*verify only*/
- {erase_pulse=0; /*void the erase instruction*/
- program_pulse=0; /*void the program instruction*/
- }
- if ((operation==verify_ues)&&(!UES)) /*The ispSTREAM has no UES*/
- return FILE_NOT_JEDEC;
-
- /*Allocate memory to store one row of data from the ispSTREAM file.*/
- buf = buffer;
- isp_pins = NUL; /* intialize to drive all port pins LOW*/
- isp_setpin(out_ISP, LOW);/* drive ispEN pin low to enable the
- ispJTAG controlling pins:
- TCK,TMS,TDI and TDO.*/
- move_to_id_state(); /* Go to Reset then Run-Test/Idle state*/
- isp_setpin(out_MODE,HIGH);
- sclock();
- isp_setpin(out_MODE,LOW);
- sclock(); sclock();
- state=execute_state; /* At shift-DR state*/
- isp_setpin(out_SDI,HIGH);
- ReadispSTREAMData(id_length,buf,SS); /*fetch ID stream from ispSTREAM*/
- rcode = ispRead(id_length,buf); /*verify the ID stream*/
- if (rcode != OK)
- return UNKNOWN_CHIP;
- program_enable(devices_in_chain);
- if (erase_pulse > 0) /*erase the devices*/
- {
- Command = ERASE_ALL;
- state=time_state;
- ispInstruction(devices_in_chain,Command);
- sclock(); /*start the erase timing*/
- pulse_width(erase_pulse); /*erase pulse*/
- isp_setpin(out_MODE, HIGH);
- isp_setpin(out_SCLK,HIGH);
- pulse_width(1); /*super voltage discharge*/
- isp_setpin(out_SCLK,LOW);
- sclock();
- isp_setpin(out_MODE,LOW);
- sclock(); sclock(); /*devices in shift state*/
- state=shift_state;
- }
- if (operation==verify_ues) /*verify ues only*/
- {for (row=1; row<EndRow; row++) /*skip array data */
- {
- if ((!HighLow)&&(row%2==0))/*single address per row HD devices*/
- {} /*devices have no Low Order rows*/
- else
- ReadispSTREAMData(maxi_data,buf,SS); /*fetch and trash ispSTREAM*/
- }
- }
- else row =1;
-
-
- /*start processing the rows in the ispSTREAM file*/
-
- for (; row <= EndRow; row++) {
- *end = row; /* The row number where process ended.*/
- if ((!HighLow)&&(row%2==0))/*single address per row HD devices*/
- {} /*devices have no Low Order rows*/
- else {
- if (row%2==1) /* Addressing for ispLSI devices*/
- {
- ispInstruction(devices_in_chain,SHIFT_ADDRESS);
- if (row==1) /* Full addressing once*/
- ispAddress(devices_in_chain,last_row);
- else {
- isp_setpin(out_MODE,HIGH);
- sclock(); execute();} /*shift to next address*/
- }
- data_length = maxi_data;
- ReadispSTREAMData(data_length,buf,SS); /*fetch data stream from ispSTREAM*/
- Command = SHIFT_DATA;
- ispInstruction(devices_in_chain,Command);
- ispData(buf,data_length); /*send data into devices*/
- if (program_pulse > 0) /*program and verify*/
- {
- if ((HighLow)&&(row%2==0)) /*Low Order rows*/
- Command = PROGRAM_LOW;
- else Command = PROGRAM_HIGH;
- if ((UES)&&(row==EndRow)) Command = PROG_USERCODE;
- state=time_state;
- ispInstruction(devices_in_chain,Command);
- sclock(); /*start program timing*/
- pulse_width(program_pulse);
- execute(); /*step to shift state*/
- }
- if ((HighLow)&&(row%2==0)) /*Low Order rows*/
- Command = VERIFY_LOW_PROG;
- else Command = VERIFY_HIGH_PROG;
- if ((UES)&&(row==EndRow)) Command = VERIFY_USERCODE;
- state=time_state;
- ispInstruction(devices_in_chain,Command);
- sclock(); /*start verify timing*/
- pulse_width(1); /*30uS min. verify time*/
- execute(); /*step to shift state*/
- Command = SHIFT_DATA;
- ispInstruction(devices_in_chain,Command);
- rcode = ispRead(data_length,buf); /*verify the data stream*/
- if (rcode != OK) break;
- }
- }
- device_enable(devices_in_chain); /*activate the devices*/
- isp_setpin(out_ISP,HIGH); /*activate the ispLSI devices*/
- if (rcode==OK) return (OK);
- else return VALIDATION_ERROR;
-
- }
-
- /*************************************************************
- * *
- * error_handler *
- * *
- * rcode - error code *
- * *
- * *
- * This procedure return the address of the message string *
- * for the corresponding error code. *
- * *
- *************************************************************/
-
- void error_handler(short int rcode, char *message)
- {
-
- char *error_message[] = {{"PASS"},{""},{""},{"PC Hardware Problem"},{""},
- {""},{""},
- {"No Device Found/Open Download Cable/Open Daisy Chain"},
- {"Can't Find the File"},{""},{"Not Enough PC Memory"},
- {"Verification Fail"},{""},{""},
- {""},
- {"The Chip Count in the Chain and the File Do Not Match"},
- {"Unknown Device Found"},{"Wrong File Type"},{"File Error"},
- {""}};
-
- strcpy(message, error_message[-rcode]);
- }
-
-
-
- /*************************************************************
- * *
- * MAIN *
- * *
- *************************************************************/
-
- short int main(short int argc, char *argv[])
- {
- short int rcode = OK,
- end = 0;
- char str[300];
-
- int operation=prog_verify; /*3.05 Default to Program and Verify*/
-
- printf("\n Lattice Semiconductor Corp.\n");
- printf("\n ispCODE V5D.000 Copyright 1996\n");
- printf("\n Slim ispSTREAM Driver for ispLSI 2000V Devices\n");
- printf("\n For Simple Chain of ISP Devices On JTAG TAP Controller\n\n");
-
- if ((argc < 1) || (argc > 2)) {
- printf("\nUsage: sjturbo [operation]\n");
- printf("Example: sjturbo pv\n");
- printf("\n");
- printf("operation \"pv\" = program and verify\n");
- printf(" \"v\" = Verify only\n");
- printf(" \"uv\" = Verify UES only\n");
- printf(" Default to pv if operation is not entered.\n");
- exit(1);
- }
-
- /*3.02 set the initial condition of the parallel port*/
- /* All the port_pins defined on lattice.h will be controlled by
- ispstream_pump(). The rest can be initialized here either to
- HIGH or LOW and won't be altered by isptream_pump*/
-
- if (rcode == OK){ /*start programming and verification*/
-
- if(!strcmp(strlwr(argv[1]),"uv")){ /*3.05 What to do? uv=ues verify only*/
- operation=verify_ues; /*for verify ues only =1*/
- printf("\nStart Verify UES of ispLSI devices.......\n");}
- else if(!strcmp(strlwr(argv[1]),"v")){ /*v = verify only*/
- operation=verify;
- printf("\nStart Verify.......\n");}
- else { /*pv = program and verify: Default*/
- operation=prog_verify;
- printf("\nStart Program and Verify.......\n");
- }
-
- rcode = ispstream_pump(operation, &end); /*3.05 add operation switch*/
- }
- if (rcode != OK) {
- error_handler(rcode, str);
- printf("\nFailed At Row %d Due To %s\n", end, str);
- printf("\n");
- printf("+-------+\n");
- printf("| FAIL! |\n");
- printf("+-------+\n");
- return (-rcode);
- } else {
- printf("\n");
- printf("+=======+\n");
- printf("| PASS! |\n");
- printf("+=======+\n");
- }
-
- return(0);
- }